OPEN(2) | Системные вызовы | OPEN(2) |
НАЗВАНИЕ¶
open, creat -- открыть и, вероятно, создать файл или устройство
КРАТКАЯ СВОДКА¶
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode);
ОПИСАНИЕ¶
Системный вызов open превращает имя файла в дескриптор файла (небольшое неотрицательное число, используемое при последующем вводе-выводе, например, с read, write, и т. п. Если системный вызов завершается успешно, возвращенный файловый дескриптор является самым маленьким дескриптором, который еще не открыт процессом. В результате этого вызова появляется новый открытый файл, не разделяемый ни с каким процессом (разделяемые открытые файлы могут возникнуть в результате системного вызова fork(2). Новый файловый дескриптор будет оставаться открытым при выполнении функции exec(2) (смотри описание fcntl(2)). Указатель в файле устанавливается в начало.
Параметр flags -- это O_RDONLY, O_WRONLY или O_RDWR, задающие, соответственно, открытие файла только для чтения, только для записи и для чтения и записи, которые можно комбинировать с помощью логического ИЛИ с нулем или более нижеследующих флагов:
- O_CREAT
- Если файл не существует, то он будет создан. Владелец (uid) файла устанавливается в фактический идентификатор владельца процесса. Группа (gid) устанавливается либо в фактический идентификатор группы процесса или же в идентификатор группы родительского каталога (зависит от типа файловой системы и флагов программы mount, а также прав доступа к родительскому каталогу. См., например, флаги bsdgroups и sysvgroups в файловой системе ext2, которые описаны в mount(8)).
- O_EXCL
- Если используется совместно с O_CREAT, то если файл уже существует, то open завершится с ошибкой. В этом контексте символьная ссылка существует, независимо от того, куда она указывает. O_EXCL не работает на файловых системах NFS, а в программах, полагающихся на этот флаг для реализации блокировки, возникнет race condition. Решение для атомарной блокировки с помощью файла: создать файл с уникальным именем на той же самой файловой системе (это имя может содержать, например, имя машины и идентификатор процесса), использовать link(2), чтобы создать ссылку на файл блокировки. Если link() возвращает 0, значит, блокировка была успешной. В противном случае используйте stat(2), чтобы убедиться, что количество ссылок на уникальный файл возросло до двух, что опять означает, что блокировка была успешной.
- O_NOCTTY
- Если pathname ссылается на терминальное устройство — см. tty(4), — то оно не станет контролирующим терминалом процесса, даже если у этого процесса нет такового.
- O_TRUNC
- Если файл уже существует, является обычным файлом, а режим открытия позволяет запись (то бишь это O_RDWR или O_WRONLY), то он будет обрезан до нулевой длины. Если файл является FIFO или устройством терминала, то флаг O_TRUNC игнорируется. В противном случае действие O_TRUNC не описано. (На многих версиях Linux этот флаг будет игнорирован; на других версиях будет возвращена ошибка.)
- O_APPEND
- Файл открывается в режиме добавления. Перед каждым write, файловый указатель перемещается в конец файла, как если бы использовался lseek. O_APPEND может привести к повреждению файлов на файловой системе NFS, если несколько процессов одновременно добавляют данные в один файл. Это происходит из-за того, что NFS не поддерживает добавление в файл, поэтому ядро на машине-клиенте должно эмулировать эту поддержку, что не может быть выполнено без race condition.
- O_NONBLOCK или O_NDELAY
- Если возможно, то файл открывается в неблокирующем режиме. Ни open, ни другие последующие операции над возвращенным дескриптором файла не заставят вызывающий процесс ждать. Работа с каналами FIFO также описана в fifo(4). Этот режим не обязан как-либо действовать на файлы, не являющиеся FIFO.
- O_SYNC
- Файл открывается в режиме синхронного ввода-вывода. Все вызовы write для соответствующего дескриптора файла блокируют вызывающий процесс до тех пор, пока данные не будут физически записаны оборудованием, на котором находится файл. Однако же, смотри в разделе ОГРАНИЧЕНИЯ.
- O_NOFOLLOW
- Если pathname -- это символическая ссылка, то open завершается с кодом ошибки. Это расширение из FreeBSD, которое было добавлено в Linux в версии 2.1.126. Все прочие символические ссылки в имени будут обработаны как обычно. Заголовочные файлы из glibc 2.0.100 и позже содержат определение этого флага; ядра с версиями меньше, чем 2.1.126, игнорируют этот флаг.
- O_DIRECTORY
- Если pathname не является каталогом, то open завершится с кодом ошибки. Этот флаг используется только в Linux, и был добавлен в ядре 2.1.126, чтобы избежать проблем с атаками типа "отказ обслуживания", если opendir(2) был вызван с каналом FIFO или ленточным устройством. Этот флаг не следует использовать вне реализации opendir.
- O_LARGEFILE
- На 32-битных системах, поддерживающих Большие Файловые Системы, этот флаг позволяет открывать файлы, длина которых не помещается в 31 бит.
Некоторые из вышеописанных флагов могут быть изменены после открытия файла с помощью fctnl.
Аргумент mode задает права доступа, которые используются в случае создания нового файла. Они модифицируются обычным способом, используя umask процесса: права доступа свежесозданного файла равны (mode & ~umask). Заметьте, что этот режим доступа относится только к последующим обращениям к свежесозданному файлу; системный вызов open, который создает новый файл только для чтения, вполне может вернуть файловый дескриптор для чтения/записи.
Нижеследующие символические константы можно использовать в mode:
- S_IRWXU
- 00700 пользователь (владелец файла) имеет права чтения, записи и выполнения.
- S_IRUSR (S_IREAD)
- 00400 пользователь имеет право чтения
- S_IWUSR (S_IWRITE)
- 00200 пользователь имеет право записи
- S_IXUSR (S_IEXEC)
- 00100 пользователь имеет право выполнения
- S_IRWXG
- 00070 группа имеет права чтения, записи и выполнения
- S_IRGRP
- 00040 группа имеет право чтения
- S_IWGRP
- 00020 группа имеет право записи
- S_IXGRP
- 00010 группа имеет право выполнения
- S_IRWXO
- 00007 все остальные имеют права чтения, записи и выполнения
- S_IROTH
- 00004 все остальные имеют право чтения
- S_IWOTH
- 00002 все остальные имеют право записи
- S_IXOTH
- 00001 все остальные имеют право выполнения
mode всегда должен быть указан при использовании O_CREAT, во всех остальных случаях этот параметр игнорируется.
creat эквивалентен open с flags, равными O_CREAT | O_WRONLY | O_TRUNC.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
open и creat возвращают новый дескриптор файла, или -1, если произошла ошибка (в этом случае errno устанавливается должным образом). Заметьте, что open может открывать файлы устройств, но creat не может создавать их -- используйте для этого mknod(2).
На файловых системах NFS с включенным преобразованием идентификаторов пользователей open может вернуть файловый дескриптор, но, например, read(2) вернет ошибку EACCES. Это из-за того, что клиент выполняет open, проверяя права доступа, но преобразование идентификаторов производится сервером при запросах на чтение и запись.
Если файл только что создан, его atime, ctime и mtime, а также ctime и mtime родительского каталога, установлены в текущее время, В противном случае если файл модифицирован из-за флага O_TRUNC, его поля ctime и mtime устанавливаются в текущее время.
ОШИБКИ¶
- EEXIST
- pathname уже существует, и были использованы O_CREAT и O_EXCL.
- EISDIR
- pathname ссылается на каталог, а тип доступа подразумевает запись.
- EACCES
- Запрошенный доступ к файлу не разрешен, или же один из каталогов в pathname не позволяет поиск (выполнение), или же файл еще не существует, а доступ для записи в родительский каталог не разрешен. error_ENAMETOOLONG(pathname) error_ENOENT(pathname)
- ENOTDIR
- Компонент, использованный как каталог в pathname, таковым не является, или был указан флаг O_DIRECTORY, а pathname не является каталогом.
- ENXIO
- Установлены O_NONBLOCK | O_WRONLY, файл является каналом FIFO, но нет процессов, которые открыли этот канал для чтения. Возможно также, что файл является файлом устройства, но соответствующее устройство не установлено.
- ENODEV
- pathname ссылается на файл устройства, но соответствующего устройства не существует. (Это ошибка в ядре Linux: должен возвращаться ENXIO.)
- EROFS
- pathname ссылается на файл, находящийся на файловой системе, смонтированной только для чтения, и был запрошен доступ для записи.
- ETXTBSY
- pathname ссылается на исполняемый файл, который в настоящее время исполняется, и был запрошен доступ для записи. error_EFAULT(pathname)
- ELOOP
- Слишком много символических ссылок было пройдено при обнаружении pathname, или был указан флаг O_NOFOLLOW, а pathname является символической ссылкой.
- ENOSPC
- pathname нужно было создать на устройстве, на котором не было места для нового файла. error_ENOMEM
- EMFILE
- Процесс уже открыл максимально допустимое количество файлов.
- ENFILE
- Достигнут предел на максимальное общее количество файлов, открытых в системе.
СООТВЕТСТВИЕ СТАНДАРТАМ¶
SVr4, SVID, POSIX, X/OPEN, BSD 4.3 Флаги O_NOFOLLOW и O_DIRECTORY специфичны для Linux. Для того, чтобы получить их определение, может потребоваться определить (через #define) символ _GNU_SOURCE.
ОГРАНИЧЕНИЯ¶
В протоколе, на котором работает NFS, существует множество недоработок, в числе прочего, оказывающих влияние на O_SYNC и O_NDELAY.
POSIX предоставляет три разных варианта синхронного ввода-вывода, соответствующего флагам O_SYNC, O_DSYNC и O_RSYNC. В настоящее время (версия 2.1.130), все они являются синонимами под Linux.
СМОТРИ ТАКЖЕ¶
read(2), write(2), fcntl(2), close(2), link(2), mknod(2), mount(2), stat(2), umask(2), unlink(2), socket(2), fopen(3), fifo(4)
ПЕРЕВОД¶
Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999-2001
June 3, 1999 | Linux |